﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JzSport.Model
{
    public class ActivityRepository
    {
        private JzSportDbContext _dbContext;

        public ActivityRepository(JzSportDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        public void Create(Activity activity)
        {
            _dbContext.Set<Activity>().Add(activity);
        }

        public Activity Get(Guid id)
        {
            return _dbContext.Set<Activity>().Where(p => p.Id == id).SingleOrDefault();
        }

        /// <summary>
        /// 查询当前城市发布最新的活动
        /// </summary>
        /// <param name="city"></param>
        /// <param name="longitude"></param>
        /// <param name="latitude"></param>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public List<Activity> GetDefaultActivityList(string city, double longitude, double latitude, int start, int limit)
        {
            return _dbContext.Database.SqlQuery<Activity>("exec [SP_GetDefaultActivityList] @city={0}, @longitude={1}, @latitude={2}, @start={3}, @limit={4}",
                         new object[] { city, longitude, latitude, start, limit }).ToList();
        }

        public int GetDefaultActivityCount(string city, double longitude, double latitude)
        {
            return _dbContext.Database.SqlQuery<int>("exec [SP_GetDefaultActivityCount] @city={0}, @longitude={1}, @latitude={2}",
                         new object[] { city, longitude, latitude }).SingleOrDefault();
        }

        public void SaveImage(ActivityImage image)
        {
            _dbContext.Set<ActivityImage>().Add(image);
        }

        public void Update(Guid id, Activity activity)
        {
            _dbContext.Entry<Activity>(activity).State = System.Data.EntityState.Modified;
        }

        public bool Delete(Guid id)
        {
            throw new NotImplementedException();
        }

        public List<Activity> GetActivityListByCategory(string city, double longitude, double latitude, string categoryCode, int page, int limit)
        {
            return _dbContext.Set<Activity>().Where(p => p.City == city && p.IsFinished != true && p.CategoryCode == categoryCode)
                .OrderBy(p => p.BeginTime)
                .Take(limit)
                .Skip(page * limit).ToList();
        }

        public int GetActivityCountByCategory(string city, double longitude, double latitude, string categoryCode)
        {
            return _dbContext.Set<Activity>().Where(p => p.City == city && p.IsFinished != true && p.CategoryCode == categoryCode)
                .Select(p => p.Id).Count();
        }

        /// <summary>
        /// 搜索所有的活动
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="city"></param>
        /// <param name="longitude"></param>
        /// <param name="latitude"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public List<Activity> SearchActivityList(string filter, string city, double longitude, double latitude, int page, int limit)
        {
            if (string.IsNullOrEmpty(filter))
            {
                return _dbContext.Set<Activity>().Where(p => p.City == city
                    && p.IsFinished != true)
                    .OrderBy(p => p.BeginTime)
                    .Take(limit)
                    .Skip(page * limit).ToList();
            }
            else
            {
                return _dbContext.Set<Activity>().Where(p => p.City == city
                    && p.IsFinished != true
                    && (p.Title.Contains(filter) || p.Address.Contains(filter)))
                    .OrderBy(p => p.BeginTime)
                    .Take(limit)
                    .Skip(page * limit).ToList();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="city"></param>
        /// <param name="longitude"></param>
        /// <param name="latitude"></param>
        /// <returns></returns>
        public int SearchActivityCount(string filter,
            string city,
            double longitude,
            double latitude)
        {
            if (string.IsNullOrEmpty(filter))
            {
                return _dbContext.Set<Activity>().Where(p => p.City == city && p.IsFinished != true)
                    .Select(p => p.Id).Count();
            }
            else
            {
                return _dbContext.Set<Activity>().Where(p => p.City == city && p.IsFinished != true
                    && (p.Title.Contains(filter) || p.Address.Contains(filter)))
                    .Select(p => p.Id).Count();
            }
        }

        public List<Activity> SearchActivityListByCategory(string filter, string city, double longitude, double latitude, string categoryCode, int page, int limit)
        {
            if (string.IsNullOrEmpty(filter))
            {
                return _dbContext.Set<Activity>().Where(p => p.City == city
                    && p.IsFinished != true
                    && p.CategoryCode == categoryCode)
                    .OrderBy(p => p.BeginTime)
                    .Take(limit)
                    .Skip(page * limit).ToList();
            }
            else
            {
                return _dbContext.Set<Activity>().Where(p => p.City == city
                    && p.IsFinished != true
                    && p.CategoryCode == categoryCode
                    && (p.Title.Contains(filter) || p.Address.Contains(filter)))
                    .OrderBy(p => p.BeginTime)
                    .Take(limit)
                    .Skip(page * limit).ToList();
            }
        }

        public int SearchActivityCountByCategory(string filter,
            string city,
            double longitude,
            double latitude,
            string categoryCode)
        {
            if (string.IsNullOrEmpty(filter))
            {
                return _dbContext.Set<Activity>().Where(p => p.City == city && p.IsFinished != true
                    && p.CategoryCode == categoryCode)
                    .Select(p => p.Id).Count();
            }
            else
            {
                return _dbContext.Set<Activity>().Where(p => p.City == city && p.IsFinished != true
                    && p.CategoryCode == categoryCode
                    && (p.Title.Contains(filter) || p.Address.Contains(filter)))
                    .Select(p => p.Id).Count();
            }
        }

        /// <summary>
        /// 获取未开始的，参加别人的未开始的活动,自己创建的排除
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public List<Activity> GetUnfinishedActivityList4User(int userId, int start, int limit)
        {
            return _dbContext.Set<Activity>().Where(p => p.IsFinished == false && p.BeginTime> DateTime.Now && p.CreatorId != userId)
                .Join(_dbContext.Set<ActivityMember>().Where(p => p.UserId == userId),
                l => l.Id,
                r => r.ActivityId,
                (l, r) => l)
                .OrderByDescending(p => p.BeginTime)
                .Skip(start).Take(limit)
                .ToList();
        }

        public int GetUnfinishedActivityCount4User(int userId)
        {
            return _dbContext.Set<Activity>().Where(p => p.IsFinished == false && p.BeginTime > DateTime.Now && p.CreatorId != userId)
                .Join(_dbContext.Set<ActivityMember>().Where(p => p.UserId == userId),
                l => l.Id,
                r => r.ActivityId,
                (l, r) => l.Id).Count();
        }

        /// <summary>
        /// 获取已参加的，自己参加的，包括自己创建的
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<Activity> GetFinishedActivityList4User(int userId, int start, int limit)
        {
            return _dbContext.Set<Activity>().Where(p => p.CreatorId != userId)
                .Join(_dbContext.Set<ActivityMember>().Where(p => p.UserId == userId),
                l => l.Id,
                r => r.ActivityId,
                (l, r) => l).Union(_dbContext.Set<Activity>().Where(p => p.CreatorId == userId))
                .OrderByDescending(p => p.BeginTime)
                .Skip(start).Take(limit)
                .ToList();
        }

        public int GetFinishedActivityCount4User(int userId)
        {
            return _dbContext.Set<Activity>().Where(p => p.CreatorId != userId)
                .Join(_dbContext.Set<ActivityMember>().Where(p => p.UserId == userId),
                l => l.Id,
                r => r.ActivityId,
                (l, r) => l).Union(_dbContext.Set<Activity>().Where(p => p.CreatorId == userId))
                .Select(p => p.Id)
                .Count();
        }

        /// <summary>
        /// 获取已发起的，所有自己创建的活动
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public List<Activity> GetUnfinishedActivityList4Creator(int userId, int start, int limit)
        {
            return _dbContext.Set<Activity>().Where(p=> p.CreatorId == userId)
                .OrderByDescending(p => p.BeginTime)
                .Skip(start).Take(limit)
                .ToList();
        }

        public int GetUnfinishedActivityCount4Creator(int userId)
        {
            return _dbContext.Set<Activity>().Where(p => p.CreatorId == userId)
                .Select(p => p.Id).Count();
        }
    }
}
